package io.github.source.media.bean;

import com.github.catvod.crawler.Spider;
import com.github.catvod.crawler.SpiderDebug;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Json;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.orhanobut.logger.Logger;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import androidx.annotation.NonNull;
import androidx.collection.ArrayMap;
import io.github.source.bean.Site;
import io.github.source.config.VodConfig;
import okhttp3.Call;
import okhttp3.Response;

/**
 * @ClassName: MediaCategoryProvider
 * @Description: TODO(分类)
 * @author: huangrongcai
 * @date: 2024/6/21
 * @Copyright: 黄嵘才（HuangRc)
 */
interface MediaCategoryProvider {
    final String TAG = "Source.Media.Play.Provider.MediaCategoryProvider";

    /**
     * 获取支持的媒体分类。
     *
     * @return 包含媒体分类的MediaResult对象，永远不会为null。
     */
    @NonNull
    MediaResult<List<MediaCategory>> getMediaCategory() throws Exception;

    interface Factory {
        MediaCategoryProvider newCall(MediaQuery query);
    }

    public static MediaCategoryProvider create() {
        return new Impl();
    }

    public static class Impl implements MediaCategoryProvider {
        @NonNull
        @Override
        public MediaResult<List<MediaCategory>> getMediaCategory() {
            try {
                Site site = VodConfig.get().getHome();
                Logger.t(TAG).d("---#getMediaCategory()-媒体分类数据---> Site=" + site);
                MediaCallback.getDefault().onMessage("媒体分类数据 Site");
                if (site == null) {
                    Logger.t(TAG).w("获取资源站点失败; Site=" + site);
                    return MediaResult.error(400).message("site为null");
                }

                int siteType = site.getType();
                if (siteType == 3) {
                    Spider spider = VodConfig.get().getSpider(site);
                    String content = spider.homeContent(true);
                    Logger.t(TAG).d("---#getMediaCategory()-媒体分类数据<--- " + content);

                    MediaResult<List<MediaCategory>> result = parseCategoryJson(site, content);

                    //首页的视频内容
                    String homeVideoContent = spider.homeVideoContent();
                    Logger.t(TAG).d("首页的视频内容<--- " + homeVideoContent);
                    MediaResult<List<MediaBean>> mediaBeans = parseMediaJson(site, homeVideoContent);
                    return result;

                } else if (siteType == 4) {
                    ArrayMap<String, String> params = new ArrayMap<>();
                    params.put("filter", "true");
                    String homeContent = call(site, params, false);
                    SpiderDebug.log(homeContent);
                    return parseCategoryJson(site, homeContent);

                } else if (siteType == 0) {/*从配置站源获取xml*/
                    String response = OkHttp.newCall(site.getApi(), site.getHeaders()).execute().body().string();
                    Logger.t(TAG).d("媒体分类数据(0)<--- " + response);
                    SpiderDebug.log(response);
                    return parseCategoryXML(site, response);

                } else if (siteType == 1) {/*从配置站源获取Json*/
                    String response = OkHttp.newCall(site.getApi(), site.getHeaders()).execute().body().string();
                    Logger.t(TAG).d("媒体分类数据(1)<--- " + response);
                    SpiderDebug.log(response);
                    return parseCategoryJson(site, response);

                } else {
                    Logger.t(TAG).e("未知的site类型: siteType=" + siteType);
                    return MediaResult.error(404).message("没有数据");
                }
            } catch (Exception e) {
                Logger.t(TAG).e("获取数据异常: " + e);
                return MediaResult.error(500).message("获取数据异常:" + e);
            }
        }


        private MediaResult<List<MediaCategory>> parseCategoryJson(Site site, String response) {
            JsonObject object = Json.parse(response).getAsJsonObject();
            //获取媒体分类数据
            ArrayList<MediaCategory> categories = new ArrayList<>();
            ArrayList mMediaBean = new ArrayList<>();
            HashMap filtersMap = new HashMap<>();
            //获取分类内容（）
            for (JsonElement element : Json.safeListElement(object, "class")) {
                MediaCategory item = MediaCategory.objectFrom(element);
                item.setSiteKey(site.getKey());
                categories.add(item);
            }
            //获取分类媒体内容（）
            for (JsonElement element : Json.safeListElement(object, "list")) {
                MediaBean item = MediaBean.objectFrom(element, site.getKey());
                mMediaBean.add(item);
            }

            //获取分类的过滤条件数据（需要先获得分类ID MediaCategory.id）
            JsonObject objectFilters = object.getAsJsonObject("filters");

            //获取过滤数据
            for (Map.Entry<String, JsonElement> entry : objectFilters.entrySet()) {
                final List<Filter> filters = new ArrayList<>();
                for (JsonElement element : Json.safeListElement(objectFilters, entry.getKey())) {
                    Filter item = Filter.objectFrom(element);
                    filters.add(item);
                }
                filtersMap.put(entry.getKey(), filters);
            }

            for (MediaCategory category : categories) {
                final List<Filter> filters = new ArrayList<>();
                category.setFilters(filters);
                filtersMap.put(category.id, filters);
                for (JsonElement element : Json.safeListElement(objectFilters, category.id)) {
                    Filter item = Filter.objectFrom(element);
                    Logger.t(TAG).d("Filter<--- " + element);
                    filters.add(item);
                }
            }

            return MediaResult.success(response, categories);
        }

        private MediaResult<List<MediaCategory>> parseCategoryXML(Site site, String response) {
            ArrayList categories = new ArrayList<>();
            MediaCategory item = MediaCategory.objectXmlFrom(response);
            return MediaResult.success(categories);
        }

        private MediaResult<List<MediaBean>> parseMediaJson(Site site, String response) {
            if (response == null || response.isEmpty()) {
                return MediaResult.error(500).message("response is null");
            }
            JsonObject object = Json.parse(response).getAsJsonObject();
            MediaResult<List<MediaBean>> result = parseMediaJson(site, object);
            result.raw(response);/*源数据*/
            return result;
        }

        /**
         * @param site   相关源战点信息
         * @param object
         * @return
         */
        private MediaResult<List<MediaBean>> parseMediaJson(Site site, JsonObject object) {
            if (object == null) {
                return MediaResult.error(500).message("object is null");
            }
            List<MediaBean> list = new ArrayList<>();
            //获取媒分类内容（）
            for (JsonElement element : Json.safeListElement(object, "list")) {
                MediaBean item = MediaBean.objectFrom(element, site.getKey());
                list.add(item);
            }
            return MediaResult.success(list);
        }

        private String call(Site site, ArrayMap<String, String> params, boolean limit) throws IOException {
            Call call = fetchExt(site, params, limit).length() <= 1000 ? OkHttp.newCall(site.getApi(), site.getHeaders(), params) : OkHttp.newCall(site.getApi(), site.getHeaders(), OkHttp.toBody(params));
            return call.execute().body().string();
        }

        private String fetchExt(Site site, ArrayMap<String, String> params, boolean limit) throws IOException {
            String extend = site.getExt();
            if (extend.startsWith("http")) extend = fetchExt(site);
            if (limit && extend.length() > 1000) extend = extend.substring(0, 1000);
            if (!extend.isEmpty()) params.put("extend", extend);
            return extend;
        }

        private String fetchExt(Site site) throws IOException {
            Response res = OkHttp.newCall(site.getExt(), site.getHeaders()).execute();
            if (res.code() != 200) return "";
            site.setExt(res.body().string());
            return site.getExt();
        }
    }

}
